/*
 * ----------------------------------------------------------------------------
 * "THE BEER-WARE LICENSE" (Revision 42):
 * <slackydude@gmail.com> and <h2one@hotmail.com> wrote this file. As long as you retain this notice you
 * can do whatever you want with this stuff. If we meet some day, and you think
 * this stuff is worth it, you can buy me a beer in return Dez.
 * ----------------------------------------------------------------------------
 */

#include "cv.h"
#include "highgui.h"
#include <stdio.h>
#include "../headers/capture.h"
#include "../headers/facedet.h"
#include "../headers/camshift_wrapper.h"
#include <time.h>
#include <curl/curl.h>




//// Constants
const char * DISPLAY_WINDOW = "DisplayWindow";
const char * BACK_PROJECTION = "BackProjection";

#define OPENCV_ROOT  "haar/"



//// Global variables
IplImage  * pVideoFrameCopy = 0;
CvCapture* capture = 0;
IplImage *frame;
IplImage *Tdist=0;
int move = 0;
double ancho = 0;
double largo = 0;
int vmin_ = 0;
int smin_ = 0;
time_t t;
long t1,t2;

//// Function definitions
int initAll();
void exitProgram(int code);
void captureVideoFrame();
static int direccion(CvBox2D box);
static int accion(CvBox2D box);
void Dibuja(IplImage * imagen,const char * DISPLAY_WINDOW);
void avanzarVmin(int id);
void avanzarSmin(int id);


//////////////////////////////////
// main()
//
int main( int argc, char** argv )
{
    CvRect * pFaceRect = 0;
    cvNamedWindow( DISPLAY_WINDOW, 1 );
    cvNamedWindow( BACK_PROJECTION, 1);

    if( !initAll() ) exitProgram(-1);
    captureVideoFrame();
    for(;;)
    {
        pFaceRect = detectFace(pVideoFrameCopy);
        Dibuja(pVideoFrameCopy,DISPLAY_WINDOW);
        if( cvWaitKey( 10 ) >= 0 )
            break;
        captureVideoFrame();
        if(pFaceRect)
            break;
        if(pFaceRect) printf("%d\n",pFaceRect->height);
    }
    startTracking(pVideoFrameCopy, pFaceRect);
    CvPoint pt1,pt2;
    CvPoint pt1r1, pt2r1, pt1r2, pt2r2, pt1r3, pt2r3, pt1r4, pt2r4;

    t=time(NULL); //toma tiempo
    t1=t;

    int dir = 0;
    trackAlmacen prueba;

    while( 1 )
    {
        CvBox2D faceBox;
        captureVideoFrame();
        prueba =track2(pVideoFrameCopy);
        faceBox = prueba.caja2d;
        ancho = pVideoFrameCopy->width;
        largo = pVideoFrameCopy->height;

//DIBUJO REGIONES
        //Region 1
        pt1r1.x = ancho/4;
        pt2r1.x = 3*ancho/4;
        pt1r1.y = 0;
        pt2r1.y = largo/4;
        cvRectangle( pVideoFrameCopy, pt1r1, pt2r1, CV_RGB(255,255,0), 3, 8, 0 );
        //Region 2
        pt1r2.x = 0;
        pt2r2.x = ancho/4;
        pt1r2.y = largo/4;
        pt2r2.y = 3*largo/4;
        cvRectangle( pVideoFrameCopy, pt1r2, pt2r2, CV_RGB(255,255,0), 3, 8, 0 );
        //Region 3
        pt1r3.x = 3*ancho/4;
        pt2r3.x = ancho;
        pt1r3.y = largo/4;
        pt2r3.y = 3* largo/4;
        cvRectangle( pVideoFrameCopy, pt1r3, pt2r3, CV_RGB(255,255,0), 3, 8, 0 );
        //Region 4
        pt1r4.x = ancho/4;
        pt2r4.x = 3*ancho/4;
        pt1r4.y = 3*largo/4;
        pt2r4.y = largo;
        cvRectangle( pVideoFrameCopy, pt1r4, pt2r4, CV_RGB(255,255,0), 3, 8, 0 );

        if(faceBox.size.width != 150)
        {
            faceBox.size.width = 150,000;
            faceBox.size.height = faceBox.size.width;
        }

        cvEllipseBox(pVideoFrameCopy, faceBox,
                     CV_RGB(255,0,0), 3, CV_AA, 0 );
        int x = (int)faceBox.center.x;
        int y = (int)faceBox.center.y;
        int w = (int)faceBox.size.width/2;
        int h = (int)faceBox.size.height/2;
        pt1.x = x - w;
        pt2.x = x + w;
        pt1.y = y - h;
        pt2.y = y + h;
        dir = direccion(faceBox);
        CURL *curl;
        CURLcode res;
        curl = curl_easy_init();
        switch (dir)
        {
        case 0:
        {

            t=time(NULL);
            t2=t;
            if ((t2-t1)==4)
            {
                int accn = accion(faceBox);
                switch (accn)
                {
                case 1:
                {
                    printf("PLAY/PAUSE\n");
                    t=time(NULL);
                    t1=t;
                    curl_easy_setopt(curl, CURLOPT_URL, "localhost:8800/xbmcCmds/xbmcHttp?command=Pause");
                    res = curl_easy_perform(curl);
                    curl_easy_cleanup(curl);
                    break;
                }
                case 2:
                {
                    printf("PLAY NEXT\n");
                    t=time(NULL);
                    t1=t;
                    curl_easy_setopt(curl, CURLOPT_URL, "localhost:8800/xbmcCmds/xbmcHttp?command=PlayNext");
                    res = curl_easy_perform(curl);
                    curl_easy_cleanup(curl);
                    break;
                }
                case 3:
                {
                    printf("ENTER\n");
                    t=time(NULL);
                    t1=t;
                    curl_easy_setopt(curl, CURLOPT_URL, "localhost:8800/xbmcCmds/xbmcHttp?command=SendKey(256)");
                    res = curl_easy_perform(curl);
                    curl_easy_cleanup(curl);
                    break;
                }
                case 4:
                {
                    printf("BACK\n");
                    t=time(NULL);
                    t1=t;
                    curl_easy_setopt(curl, CURLOPT_URL, "localhost:8800/xbmcCmds/xbmcHttp?command=SendKey(275)");
                    res = curl_easy_perform(curl);
                    curl_easy_cleanup(curl);
                    break;
                }
                }
                break;
            }
            break;
        }
        case 1:
        {
            t=time(NULL);
            t1=t;
            printf("Arriba\n");

            curl_easy_setopt(curl, CURLOPT_URL, "localhost:8800/xbmcCmds/xbmcHttp?command=SendKey(270)");
            res = curl_easy_perform(curl);
            curl_easy_cleanup(curl);
            break;
        }
        case 3:
        {
            t=time(NULL);
            t1=t;
            printf("Izquierda\n");
            curl_easy_setopt(curl, CURLOPT_URL, "localhost:8800/xbmcCmds/xbmcHttp?command=SendKey(272)");
            res = curl_easy_perform(curl);
            curl_easy_cleanup(curl);
            break;
        }
        case 2:
        {
            t=time(NULL);
            t1=t;
            printf("Derecha\n");
            curl_easy_setopt(curl, CURLOPT_URL, "localhost:8800/xbmcCmds/xbmcHttp?command=SendKey(273)");
            res = curl_easy_perform(curl);
            curl_easy_cleanup(curl);
            break;
        }
        case 4:
        {
            t=time(NULL);
            t1=t;
            printf("Abajo\n");
            curl_easy_setopt(curl, CURLOPT_URL, "localhost:8800/xbmcCmds/xbmcHttp?command=SendKey(271)");
            res = curl_easy_perform(curl);
            curl_easy_cleanup(curl);
            break;
        }
        default:
        {
            t=time(NULL);
            t1=t;
            break;
        }
        }


        cvRectangle(pVideoFrameCopy,pt1,pt2,CV_RGB(255,0,0),3,8,0);
        Dibuja(pVideoFrameCopy,DISPLAY_WINDOW);
        Dibuja(prueba.back,BACK_PROJECTION);

        if( cvWaitKey( 10 ) >= 0 )
            break;
    }

    return 0;
}


//////////////////////////////////
// initAll()
//
int initAll()
{
    if( !initCapture() ) return 0;
    if( !initFaceDet(OPENCV_ROOT
                     "aGest.xml"))
        return 0;
    printf( "\n********************************************\n"
            "Presiona Enter para empezar." );
    fgetc(stdin);

    cvCreateTrackbar("Vmin",BACK_PROJECTION,&vmin_,255,avanzarVmin);
    cvCreateTrackbar("Smin",BACK_PROJECTION,&smin_,255,avanzarSmin);

    captureVideoFrame();
    if( !createTracker(pVideoFrameCopy) ) return 0;

    setVmin(60);
    setSmin(50);

    return 1;
}


//////////////////////////////////
// exitProgram()
//
void exitProgram(int code)
{
    // Release resources allocated in this file
    cvDestroyWindow( DISPLAY_WINDOW );
    cvReleaseImage( &pVideoFrameCopy );

    // Release resources allocated in other project files
    closeCapture();
    closeFaceDet();
    releaseTracker();

    exit(code);
}

//////////////////////////////////
// Draw tha shit()
//
void Dibuja(IplImage * imagen, const char * DISPLAY_WINDOW )
{
    cvFlip(imagen, NULL, 1);
    cvShowImage( DISPLAY_WINDOW, imagen );
}
//////////////////////////////////
// captureVideoFrame()
//
void captureVideoFrame()
{
    IplImage  * pVideoFrame = nextVideoFrame();
    if( !pVideoFrame ) exitProgram(-1);

    if( !pVideoFrameCopy )
        pVideoFrameCopy = cvCreateImage( cvGetSize(pVideoFrame), 8, 3 );
    cvCopy( pVideoFrame, pVideoFrameCopy, 0 );
    pVideoFrameCopy->origin = pVideoFrame->origin;
}

static int accion(CvBox2D box)
{

    if (ancho/4<box.center.x && box.center.x<ancho/2 && largo/4<box.center.y && box.center.y<largo/2 )
    {
        return 1; //pause play
    }
    if (ancho/2<box.center.x && box.center.x<3*ancho/4 && largo/4<box.center.y && box.center.y<largo/2 )
    {
        return 2; //stop
    }
    if (ancho/4<box.center.x && box.center.x<ancho/2 && largo/2<box.center.y && box.center.y<3*largo/4 )
    {
        return 3; //enter
    }
    if (ancho/2<box.center.x && box.center.x<3*ancho/4 && largo/2<box.center.y && box.center.y<3*largo/4)
    {
        return 4; //back
    }
    return 0;
}
static int direccion(CvBox2D box)
{

    if (ancho/4<box.center.x && box.center.x<3*ancho/4 && 0<box.center.y && box.center.y<largo/4 )
    {
        if (move == 0) //4
        {
            move = 1;
            return 1; //arriba
        }
        move = 1;
    }
    if (0<box.center.x && box.center.x<ancho/4 && largo/4<box.center.y && box.center.y<3*largo/4 )
    {
        if (move == 0) //3
        {
            move = 2;
            return 2; //izquierda
        }
        move = 2;
    }

    if (3*ancho/4<box.center.x && box.center.x<ancho && largo/4<box.center.y && box.center.y<3*largo/4 )
    {
        if (move == 0) //2
        {
            move = 3;
            return 3; //derecha
        }
        move = 3;
    }
    if (ancho/4<box.center.x && box.center.x<3*ancho/4 && 3*largo/4<box.center.y && box.center.y<largo)
    {
        if (move == 0) //1
        {
            move = 4;
            return 4; //abajo
        }
        move = 4;
    }
    if (ancho/4<box.center.x && box.center.x<3*ancho/4 && largo/4<box.center.y && box.center.y<3*largo/4)
    {
        move = 0;
        return 0;
    }
    return 5;
}

void avanzarVmin(int id)
{
    vmin_=vmin_+5;
    setVmin(vmin_);
}
void avanzarSmin(int id)
{
    smin_=smin_+5;
    setSmin(smin_);
}
